package com.seed.util;

import cn.hutool.core.util.StrUtil;
import com.mybatisflex.core.query.QueryColumn;
import com.mybatisflex.core.query.QueryCondition;
import com.mybatisflex.core.query.QueryTable;
import com.seed.core.builder.pojo.OnCondition1;
import com.seed.core.builder.pojo.Table1;
import com.seed.core.builder.pojo.WhereCondition1;
import com.seed.core.enumeration.SqlOp;

import java.util.List;
import java.util.Map;
import java.util.stream.Stream;

public class ConditionKit {

    public static QueryCondition build(WhereCondition1 c) {
        Table1 table1 = c.getTable();
        return build(table1.getName(), table1.getAlias(), c.getColumn(), c.getOp(), c.getValue());
    }

    public static QueryCondition build(String tableName, String tableAlias, String columnName, SqlOp op, Object value) {
        QueryTable queryTable = new QueryTable(tableName).as(tableAlias);
        QueryColumn queryColumn = new QueryColumn(queryTable, columnName);
        if(op != SqlOp.isNull && op != SqlOp.isNotNull && StrUtil.isBlank((CharSequence) value)) {
            return QueryCondition.createEmpty();
        }

        return switch (op) {
            case like -> queryColumn.like(value);
            case likeLeft -> queryColumn.likeLeft(value);
            case likeRight -> queryColumn.likeRight(value);
            case notLike -> queryColumn.notLike(value);
            case notLikeLeft -> queryColumn.notLikeLeft(value);
            case notLikeRight -> queryColumn.notLikeRight(value);
            case eq -> queryColumn.eq(value);
            case ne -> queryColumn.ne(value);
            case gt -> queryColumn.gt(value);
            case ge -> queryColumn.ge(value);
            case lt -> queryColumn.lt(value);
            case le -> queryColumn.le(value);
            case isNull -> queryColumn.isNull();
            case isNotNull -> queryColumn.isNotNull();
            case in -> queryColumn.in(toList(value));
            case notIn -> queryColumn.notIn(toList(value));
            case between -> {
                List<String> values = toList(value);
                int size = values.size();
                if(size == 1) yield queryColumn.eq(values.get(0));
                yield queryColumn.between(values.get(0), values.get(1));
            }
            case notBetween -> {
                List<String> values = toList(value);
                int size = values.size();
                if(size == 1) yield queryColumn.ne(values.get(0));
                yield queryColumn.notBetween(values.get(0), values.get(1));
            }
        };
    }

    public static QueryCondition build(OnCondition1 c) {
        Table1 selfTable = c.getSelfTable();
        String selfColumn = c.getSelfColumn();
        Table1 targetTable = c.getTargetTable();
        String targetColumn = c.getTargetColumn();
        Map<String, Object> extra = c.getExtra();

        QueryTable selfTable1 = new QueryTable(selfTable.getName()).as(selfTable.getAlias());
        QueryTable targetTable1 = new QueryTable(targetTable.getName()).as(targetTable.getAlias());
        QueryCondition ret = new QueryColumn(selfTable1, selfColumn).eq(new QueryColumn(targetTable1, targetColumn));
        for(Map.Entry<String, Object> entry: extra.entrySet()) {
            ret.and(new QueryColumn(selfTable1, entry.getKey()).eq(entry.getValue()));
        }

        return ret;
    }

    private static List<String> toList(Object value) {
        return Stream.of(value.toString().split(","))
                .filter(StrUtil::isBlank)
                .map(e -> e.trim())
                .distinct()
                .toList();
    }
}
